#include <algorithm>

#include "render_sys.h"
#include "city.h"
#include "map.h"
#include "tile.h"
#include "camera.h"
#include "buildable.h"
#include "gui/gui.h"
#include "gui/gui_controller.h"

//////////////////////////////////////////////////
//  RenderSys::RenderSys()
//////////////////////////////////////////////////
RenderSys::RenderSys() :
    camera(NULL)
{

}

//////////////////////////////////////////////////
//  bool RenderSys::init()
//////////////////////////////////////////////////
sf::RenderWindow* RenderSys::init()
{
    window.create(sf::VideoMode(800, 600, 32), "iso-map");
    //window.ShowMouseCursor(false);
    window.setFramerateLimit(60);

    // Camera
    camera = new Camera;
    window.setView(*camera->getView());

    if (window.isOpen())
    {
        return &window;
    }
    else
    {
        return NULL;
    }
}

//////////////////////////////////////////////////
//  void RenderSys::eventHandle(sf::Event event)
//////////////////////////////////////////////////
void RenderSys::eventHandle(sf::Event event)
{
    camera->eventHandle(event);
}

//////////////////////////////////////////////////
//  void RenderSys::update(double dt)
//////////////////////////////////////////////////
sf::Vector2i mouseTileCoords;
void RenderSys::update(double dt)
{
    // Update subsystems
    camera->update(dt);
}

//////////////////////////////////////////////////
//  void RenderSys::render()
//////////////////////////////////////////////////
void RenderSys::render(Gui* gui, City* city)
{
    window.clear(sf::Color(194, 242, 242, 200));
    window.setView(*camera->getView());

    drawTiles(city->getMap());
    drawBuildables(city);

    // Set original view so that gui is not offset by the camera
    window.setView(window.getDefaultView());
    gui->render(window);
    window.display();
}

//////////////////////////////////////////////////
//  void RenderSys::drawTiles(Map* map)
//////////////////////////////////////////////////
void RenderSys::drawTiles(Map* map)
{
    Tile* current = NULL;
    int tileSizeX = 16;
    int tileSizeY = 8;


    for (int y = 0; y < map->getHeight(); y++)
    {
        for (int x = 0; x < map->getWidth(); x++)
        {
            current = map->getTile(x, y);

            if (current != NULL)
            {
                sf::Sprite* sprite = current->getSprite();
                sprite->setOrigin(0, sprite->getLocalBounds().height - 16);

                sprite->setPosition(x*tileSizeX - y*tileSizeX, x*tileSizeY + y*tileSizeY);

                if (current->isHighlighted())
                {
                    sprite->setColor(sf::Color(128, 128, 128, 255));
                }
                else
                {
                    sprite->setColor(sf::Color::White);
                }

                window.draw(*sprite);
            }
        }
    }
}

//////////////////////////////////////////////////
//  void RenderSys::drawBuildables(City* city)
//////////////////////////////////////////////////
void RenderSys::drawBuildables(City* city)
{
    Tile* current = NULL;
    int tileSizeX = 16;
    int tileSizeY = 8;


    for (auto &buildable : city->getBuildables())
    {
        sf::Sprite* sprite = buildable->getSprite();

        sf::Vector2i origin = buildable->getOrigin();
        sprite->setOrigin(0, sprite->getLocalBounds().height - 16);
        sprite->setPosition(origin.x*tileSizeX - origin.y*tileSizeX, origin.x*tileSizeY + origin.y*tileSizeY);

        window.draw(*sprite);
    }

}
